package br.usp.pcs.basys.event;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import br.usp.pcs.basys.Job;
import br.usp.pcs.basys.engine.UnavaiableResourceException;
import br.usp.pcs.basys.engine.IResources;

public class ProcessorRequest extends ComputerSystemEvent {

	public ProcessorRequest(Job job, Date date, IResources resources) {
		super(job, date, resources);
	}

	@Override
	List<ActionResult> run() {
		List<ActionResult> result = new ArrayList<ActionResult>();
		try {
			resources.reserveProcessor();
			if (job.hasPendingRecords()) {
				result.add(scheduleProcessorReleaseForDiskRequest());
				job.decrementRecordCount();
			}
			else {
				result.add(scheduleJobCompletion());
			}
		} catch (UnavaiableResourceException e) {
			resources.queue(this);
			result.add(new EventQueueResult(this));
		}
		return result;
	}

	private ActionResult scheduleJobCompletion() {
		ComputerSystemEvent nextEvent = new JobCompletion(job,date,resources);
		resources.add(nextEvent);
		ActionResult result = new ScheduledEventResult(nextEvent);
		return result;
	}

	private ActionResult scheduleProcessorReleaseForDiskRequest() {
		Long duration = job.getMeanInterrequestTime();
		Date nextEventDate = getDateAfterWaiting(duration);
		ComputerSystemEvent nextEvent = new ReleaseCPUForDisk(job,nextEventDate,resources);
		resources.add(nextEvent);
		ActionResult result = new ScheduledEventResult(nextEvent);
		return result;
	}

}
